
# ******************************************************
# * Copyright © 2016-2023 - Jordan Irwin (AntumDeluge) *
# ******************************************************
# * This software is licensed under the MIT license.   *
# * See: LICENSE.txt for details.                      *
# ******************************************************

## @module input.select

import wx

from wx.adv import OwnerDrawnComboBox

from fields.ifield   import InputField
from input.essential import EssentialField
from libdbr          import strings
from ui.font         import MONOSPACED_MD


## Custom wx.Choice class.
class Choice(wx.Choice, InputField):
  def __init__(self, parent, win_id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize,
      choices=[], style=0, validator=wx.DefaultValidator, name=wx.ChoiceNameStr,
      defaultValue=0, required=False, outLabel=None):
    wx.Choice.__init__(self, parent, win_id, pos, size, choices, style, validator, name)
    InputField.__init__(self, defaultValue, required, outLabel)

  ## Set available values.
  #
  #  @param items
  #    List of items to be set.
  def Set(self, items):
    cached_value = self.GetStringSelection()
    if not isinstance(items, (tuple, list, dict,)):
      items = (items,)
    wx.Choice.Set(self, items)
    if cached_value:
      self.SetStringSelection(cached_value)


## Choice class that notifies main window to mark the project dirty.
#
#  This is a dummy class to facilitate merging to & from unstable branch.
class ChoiceESS(Choice, EssentialField):
  def __init__(self, parent, win_id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize,
      choices=[], style=0, validator=wx.DefaultValidator, name=wx.ChoiceNameStr,
      defaultValue=0, required=False, outLabel=None):

    Choice.__init__(self, parent, win_id, pos, size, choices, style, validator, name,
        defaultValue, required, outLabel)
    EssentialField.__init__(self)


## Custom combo box that sets background colors when enabled/disabled.
#
#  This is a workaround for wx versions older than 3.0.
#
#  Notes on processing combo box events (EVT_COMBOBOX)
#  wx 2.8:
#  	wx.combo.OwnerDrawnComboBox
#  		- Keyboard:	 Emits EVT_TEXT
#  		- Drop-down:	Emits EVT_COMBOBOX & 2 EVT_TEXT
#  		- Mouse scroll: Does nothing
#  	wx.ComboBox
#  		- Keyboard:	 Emits EVT_TEXT
#  		- Drop-down:	Emits EVT_COMBOBOX & EVT_TEXT
#  		- Mouse scroll: Emits EVT_COMBOBOX & EVT_TEXT (Note: Doesn't scroll until after drop-down select)
#  wx 3.0:
#  	wx.combo.OwnerDrawnComboBox
#  		- Keyboard:	 Emits EVT_TEXT
#  		- Drop-down:	Emits EVT_COMBOBOX & 2 EVT_TEXT
#  		- Mouse scroll: Emits EVT_COMBOBOX
#  		Other Notes: Mouse scroll emits EVT_KEY_DOWN
#  	wx.ComboBox
#  		- Keyboard:	 Emits EVT_TEXT
#  		- Drop-down:	Emits EVT_COMBOBOX & EVT_TEXT
#  		- Mouse scroll: Emits EVT_COMBOBOX & EVT_TEXT (Note: Doesn't scroll until after drop-down select)
class ComboBox(OwnerDrawnComboBox, InputField):
  def __init__(self, parent, win_id=wx.ID_ANY, value=wx.EmptyString, pos=wx.DefaultPosition,
      size=wx.DefaultSize, choices=[], style=0, validator=wx.DefaultValidator,
      name=wx.ComboBoxNameStr, monospace=False, defaultValue=wx.EmptyString,
      required=False, outLabel=None):

    OwnerDrawnComboBox.__init__(self, parent, win_id, value, pos, size, choices, style,
        validator, name)
    InputField.__init__(self, defaultValue, required, outLabel)

    if wx.MAJOR_VERSION < 3:
      self.clr_disabled = self.GetBackgroundColour()
      self.clr_enabled = self.GetTextCtrl().GetBackgroundColour()

    if monospace:
      self.GetTextCtrl().SetFont(MONOSPACED_MD)
      # FIXME: This doesn't work (use monospace in popup list)
      self.GetPopupControl().GetControl().SetFont(MONOSPACED_MD)

  ## @todo Doxygen
  def Disable(self):
    return self.Enable(False)

  ## @todo Doxygen
  def Enable(self, *args, **kwargs):
    return_value =  OwnerDrawnComboBox.Enable(self, *args, **kwargs)
    if wx.MAJOR_VERSION < 3:
      text_area = self.GetTextCtrl()
      if self.IsEnabled():
        text_area.SetBackgroundColour(self.clr_enabled)
      else:
        text_area.SetBackgroundColour(self.clr_disabled)
    return return_value

  ## Override inherited method for compatibility with older wx versions.
  #
  #  @param items
  #    \b \e String or \b \e list of string items.
  def Set(self, items):
    # Text control is cleared when options are changed
    cached_value = self.GetValue()
    if not isinstance(items, (tuple, list, dict)):
      items = (items,)
    if wx.MAJOR_VERSION > 2:
      OwnerDrawnComboBox.Set(self, items)
    else:
      self.Clear()

      for I in items:
        self.Append(I)
    if not strings.isEmpty(cached_value):
      self.SetValue(cached_value)


## ComboBox class that notifies main window to mark the project dirty.
#
#  This is a dummy class to facilitate merging to & from unstable branch.
class ComboBoxESS(ComboBox, EssentialField):
  def __init__(self, parent, win_id=wx.ID_ANY, value=wx.EmptyString, pos=wx.DefaultPosition,
      size=wx.DefaultSize, choices=[], style=0, validator=wx.DefaultValidator,
      name=wx.ComboBoxNameStr, monospace=False, defaultValue=wx.EmptyString,
      required=False, outLabel=None):

    ComboBox.__init__(self, parent, win_id, value, pos, size, choices, style, validator,
        name, monospace, defaultValue, required, outLabel)
    EssentialField.__init__(self)
